/**
 * 习题类的单元测试
 * 测试Exercise类的所有功能
 */
public class ExerciseTest {
    
    /**
     * 测试习题集的创建和基本属性
     */
    public static void testExerciseCreation() {
        Exercise exercise = new Exercise(10);
        
        // 测试基本属性
        assert exercise.getTotalCount() == 10 : "习题总数错误";
        assert exercise.getCorrectCount() == 0 : "初始正确计数错误";
        assert exercise.getAccuracy() == 0.0 : "初始正确率错误";
        
        // 测试获取算式
        for (int i = 0; i < 10; i++) {
            Calculation calc = exercise.getCalculation(i);
            assert calc != null : "算式对象为空";
            
            // 验证算式的有效性（结果不超过100，减法结果不为负数）
            if (calc.getOperator() == '+') {
                assert calc.getResult() <= 100 : "加法结果超出范围";
            } else if (calc.getOperator() == '-') {
                assert calc.getResult() >= 0 : "减法结果为负数";
            }
        }
        
        // 测试习题字符串生成
        String[] exerciseStrings = exercise.getExerciseStrings();
        assert exerciseStrings.length == 10 : "习题字符串数组长度错误";
    }
    
    /**
     * 测试答题功能
     */
    public static void testAnswerQuestion() {
        // 创建一个包含已知答案的习题集（通过模拟特定的随机数序列）
        // 为了简单测试，我们直接使用已知的算式来验证答题功能
        Exercise exercise = new Exercise(5);
        
        // 获取前两个算式并回答
        Calculation calc1 = exercise.getCalculation(0);
        Calculation calc2 = exercise.getCalculation(1);
        
        // 回答第一个问题（正确答案）
        boolean result1 = exercise.answerQuestion(0, calc1.getResult());
        assert result1 : "正确答案未被识别";
        assert exercise.getCorrectCount() == 1 : "正确计数未更新";
        
        // 回答第二个问题（错误答案）
        boolean result2 = exercise.answerQuestion(1, calc2.getResult() + 1);
        assert !result2 : "错误答案被错误识别";
        assert exercise.getCorrectCount() == 1 : "错误答案不应增加正确计数";
        
        // 回答第一个问题（再次回答，这里简化处理，实际应用可能需要更复杂的状态管理）
        boolean result3 = exercise.answerQuestion(0, calc1.getResult());
        assert result3 : "正确答案再次验证失败";
        // 注意：在当前实现中，同一个问题多次回答正确会重复计数
        // 在实际应用中可能需要修改这一行为
    }
    
    /**
     * 测试成绩计算
     */
    public static void testScoreCalculation() {
        Exercise exercise = new Exercise(10);
        
        // 回答一半的问题正确
        for (int i = 0; i < 5; i++) {
            Calculation calc = exercise.getCalculation(i);
            exercise.answerQuestion(i, calc.getResult());
        }
        
        // 回答另一半的问题错误
        for (int i = 5; i < 10; i++) {
            Calculation calc = exercise.getCalculation(i);
            exercise.answerQuestion(i, calc.getResult() + 1);
        }
        
        // 验证成绩
        assert exercise.getCorrectCount() == 5 : "正确计数错误";
        assert exercise.getAccuracy() == 50.0 : "正确率计算错误";
    }
    
    /**
     * 测试边界情况和异常处理
     */
    public static void testBoundaryAndExceptions() {
        Exercise exercise = new Exercise(5);
        
        // 测试索引越界异常
        boolean exceptionCaught = false;
        try {
            exercise.getCalculation(10); // 超出范围的索引
        } catch (IndexOutOfBoundsException e) {
            exceptionCaught = true;
        }
        assert exceptionCaught : "索引越界异常未抛出";
        
        exceptionCaught = false;
        try {
            exercise.answerQuestion(-1, 0); // 无效索引
        } catch (IndexOutOfBoundsException e) {
            exceptionCaught = true;
        }
        assert exceptionCaught : "无效索引异常未抛出";
        
        // 测试空习题集（边界情况）
        // 在实际应用中，可能需要在构造函数中检查totalCount是否为正整数
    }
    
    /**
     * 主方法 - 运行所有测试
     */
    public static void main(String[] args) {
        System.out.println("开始习题类单元测试...");
        
        testExerciseCreation();
        System.out.println("习题创建测试通过！");
        
        testAnswerQuestion();
        System.out.println("答题功能测试通过！");
        
        testScoreCalculation();
        System.out.println("成绩计算测试通过！");
        
        testBoundaryAndExceptions();
        System.out.println("边界和异常处理测试通过！");
        
        System.out.println("所有测试通过！习题类功能正常。");
    }
}